package com.uade.magicCompany.dao;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;


public abstract class AbstractBaseGenericDAOImpl<T, K extends Serializable>
		implements BaseGenericDAO<T, K> {

	EntityManagerFactory emf;
	protected EntityManager em;

	protected Class<T> classType;

	public AbstractBaseGenericDAOImpl() {
		super();
		this.classType = (Class<T>) getParameterClass(getClass(), 0);

	}

	@Override
	public T create(T entity) {

		// Get the entity manager for the tests.
		emf = Persistence.createEntityManagerFactory("JEE6Demo-Persistence");
		em = emf.createEntityManager();
		try {
			// Get a new transaction
			EntityTransaction trx = em.getTransaction();

			// Start the transaction
			trx.begin();
			// Persist the object in the DB
			this.em.persist(entity);
			// Commit and end the transaction
			trx.commit();
		} catch (RuntimeException e) {
			// if (trx != null && trx.isActive()) {
			// trx.rollback();
			// }
			throw e;
		} finally {
			// Close the manager
			em.close();
			emf.close();
		}

		return entity;
	}

	@Override
	public T update(T entity) {

		emf = Persistence.createEntityManagerFactory("JEE6Demo-Persistence");
		em = emf.createEntityManager();
		try {
			// Get a new transaction
			EntityTransaction trx = em.getTransaction();

			// Start the transaction
			trx.begin();
			// Persist the object in the DB
			T t = this.em.merge(entity);
			// Commit and end the transaction
			trx.commit();
			return t;
		} catch (RuntimeException e) {
			// if (trx != null && trx.isActive()) {
			// trx.rollback();
			// }
			throw e;
		} finally {
			// Close the manager
			em.close();
			emf.close();
		}

	}

	@Override
	public void delete(T entity) {
		emf = Persistence.createEntityManagerFactory("JEE6Demo-Persistence");
		em = emf.createEntityManager();
		try {
			// Get a new transaction
			EntityTransaction trx = em.getTransaction();

			// Start the transaction
			trx.begin();
			// Remove the object in the DB
			this.em.remove(entity);
			// Commit and end the transaction
			trx.commit();
		} catch (RuntimeException e) {
			// if (trx != null && trx.isActive()) {
			// trx.rollback();
			// }
			throw e;
		} finally {
			// Close the manager
			em.close();
			emf.close();
		}
	}

	@Override
	public T findById(K key) {

		emf = Persistence.createEntityManagerFactory("JEE6Demo-Persistence");
		em = emf.createEntityManager();
		try {
			// Get a new transaction
			EntityTransaction trx = em.getTransaction();

			// Start the transaction
			trx.begin();
			// Remove the object in the DB
			T t = this.em.find(classType, key);
			// Commit and end the transaction
			trx.commit();
			return t;
		} catch (RuntimeException e) {
			// if (trx != null && trx.isActive()) {
			// trx.rollback();
			// }
			throw e;
		} finally {
			// Close the manager
			em.close();
			emf.close();
		}
	}

	private static Class<?> getParameterClass(Class<?> clazz, int index) {
		return (Class<?>) (((ParameterizedType) clazz.getGenericSuperclass())
				.getActualTypeArguments()[index]);
	}
	
	protected void getEntityManager(){
		
	}
}
